import axios from "axios";
import Nprogress from 'nprogress'
import 'nprogress/nprogress.css'
import { $msg_success, $msg_error } from './msg';
import { getToken, setToken, removeToken, getRefreshToken, setRefreshToken } from '@/caches/Token'


// request.js
// 创建新的axios实例
const axiosService = axios.create({
    // 环境变量，需要在.env文件中配置
    baseURL: import.meta.env.VUE_APP_BASE_API,
    // 超时时间暂定5s
    timeout: 5000,  // 30000
     //自定义请求头
    headers: {'X-Custom-Header': 'ucms'}
    //headers: { 'authorization': 'Bearer '  + sessionStorage.getItem('singletonKey') },
  });

  // 添加请求拦截器
  axiosService.interceptors.request.use(
    config => {
      // 在发送请求之前做些什么
      Nprogress.start();  // 此处添加Loading
      const token = getToken();
      console.log(token)
      // if (token) config.headers.authorization = 'Bearer ' + token;
      config.headers.authorization = 'Bearer ' + token;  // here
      console.log(config)
      return config;
    },
    error => {
      // 对请求错误做些什么
      Nprogress.done();
      return Promise.reject(error);
    }
  );


  // 是否正在刷新 token
  let isNotRefreshing = true;
  //请求队列
  let request_quee:any = [];

  // 添加响应拦截器
  axiosService.interceptors.response.use(async (response:any) => {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    Nprogress.done();
    const msgCode = response.data.msgCode;
    console.log(msgCode)
    if (msgCode == 5555) {
      // 响应配置参数，包括了url、data等信息，用这个config进行重发
      const config = response.config;
      //进行token刷新操作
      if (isNotRefreshing) {
        isNotRefreshing = false;
        return await $refreshToken().then((res:any) => {
          console.log(res)
          if (res.msgCode === '200') {
            setToken(res.appMsg.token)
            setRefreshToken(res.appMsg.refreshToken);
            // sessionStorage.setItem("qatSingletonKey", res.data[0].token);
            // localStorage.setItem('qatRefreshToken', res.data[0].refreshToken);
            // $setToken;
            request_quee.forEach((run:any)=> run());
            request_quee = [];
            console.log('token已更新！');
            return axiosService(config);
        }
        else {
            $msg_error('Token已过期，请重新登录！');
            removeToken();
            // sessionStorage.removeItem('qatSingletonKey');
            // sessionStorage.removeItem('qatAskState');
            // router.replace('/login');  登陆未完成
        }
        }).finally(() => {
          isNotRefreshing = true;
        })
      } else {
        //如果当前是刷新token状态，就将请求置于请求队列中，队列会在刷新token的回调中执行，new关键字存在声明提升，不用考虑会有请求没有处理完的情况，请求一定会在刷新token回调执行之前执行
        return new Promise(resolve => {
            //promise解析函数，将响应的config配置对应解析的请求函数存到requests中，等刷新token回调后再执行
            request_quee.push(() => {
                resolve(axiosService(config));
            })
        })
      }




    }
    return response;
  }, function (error:any) {
    // 非自定义失败
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    Nprogress.done();

     // 当响应异常时
     const isTimeout = error.toString().includes('timeout')
     if (isTimeout) {
         $msg_error('请求响应超时！');
     }
     const state = error.response.status;
     switch (state) {
      case 401: $msg_error('Token已过期，请重新登录！');
          removeToken();
          // sessionStorage.removeItem('qatSingletonKey');
          // router.replace({
          //     path: '/login',
          //     query: { redirect: router.currentRoute.fullPath }  // router对象自带的属性
          // });
          break;
      case 404: $msg_error('网络请求不存在！');
          break;
      case 429: $msg_error('请求太频繁，请稍后再试！');
          break;
  }

    return Promise.reject(error);
});

// export {axiosService};

export default axiosService;

// 消息过滤
const msgFilter = (data:any) => {
  if (data.msgCode === '200') {
      if (data.msgCodeName) $msg_success(data.msgCodeName);
      return data.appMsg;
  }
  else {
    const errorInfo = data.msgCodeName ? data.msgCodeName : data
    $msg_error(errorInfo);
  }
  return false;
}

// 刷新token
const $refreshToken = async () => {
  // 模拟测试 userinfo
  const userinfo = {
    account:'testAAA'
  }
  // const userinfo = getLogins();
  const refreshToken = getRefreshToken();

  const params = { 'account': userinfo.account, 'refreshToken': refreshToken, };
  const res = await axiosService.put('/common/refreshtoken', params);
  return res.data;
}

// get请求
export const $get = async (url:string) => {
  console.log('get请求数据：' + url);
  const { data } = await axiosService.get(url);
  console.log('get返回数据：', data);
  //return data;
  return msgFilter(data);
}

//post请求
export const $post = async (url:string, params:any) => {
  console.log('post请求数据：', params);
  const { data } = await axiosService.post(url, params);
  console.log('post返回数据：', data);
  return msgFilter(data);
}

//put请求
export const $put = async (url:string, params:any) => {
  console.log('put请求数据：', params);
  const { data } = await axiosService.put(url, params);
  console.log('put返回数据：', data);
  return msgFilter(data);
}

//delete请求
export const $delete = async (url:string) => {
  console.log('delete请求数据：' + url);
  const { data } = await axiosService.delete(url);
  console.log('delete返回数据：', data);
  return msgFilter(data);
}

//将浏览器sessionStorage里面的token信息添加到请求头中
// export let $setToken = () => {
//     axiosService.defaults.headers.common['authorization'] = 'Bearer ' + sessionStorage.getItem('qatSingletonKey');
// }